package cn.com.executor;

import cn.com.task.TaskDemo2;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.ThreadPoolExecutor;

/**
 * 普通线程池
 */
public class ExecutorThreadMainTest {

    public static void main(String[] args) throws Exception {
        //1. 构建线程池
        //fixed线程池(创建一个固定大小的线程池，如果线程超过池子大小，则超过得线程会在队列中等待，等待有线程回收后再执行，并发可控)
        ExecutorService pool = Executors.newFixedThreadPool(5);

        //cached线程池（无固定大小，最大INTEGER.MAX_VALUE,并发数不可控，如果线程量过大，可能会导致内存溢出，程序崩溃）
        //ExecutorService pool = Executors.newCachedThreadPool();

        //单线程（线程池大小为1，超过的线程会在队列等待，等待有线程回收后再执行）
        //ExecutorService pool = Executors.newSingleThreadScheduledExecutor();

        //Scheduled线程池（定时线程池，可执行周期任务）
        //ExecutorService pool = Executors.newScheduledThreadPool(5);


        //2. 接收多线程的返回值（注意这里把线程提交pool的时候就开始执行了，不算并行执行，只能算并发执行）
        List<Future<Integer>> futures = new ArrayList<Future<Integer>>();
        for (int i = 0; i < 6; i++) {
            TaskDemo2 targetDemo = new TaskDemo2(i);
            //这里尽量不要使用execute，因为execute不能给主线程返回值，并且不能处理线程里的异常，如果用execute还不如使用简单的Thread、Runnable算了
            Future<Integer> future = pool.submit(targetDemo);
            futures.add(future);
        }

        //3. 关闭线程池，不再接收任何线程
        pool.shutdown();

        //4. 获取线程的返回值
        for (Future<Integer> future : futures) {
            //这里future.get()会阻塞等待返回值future对应的线程执行完成拿到返回值
            System.out.println(future.get());
        }

        System.out.println("执行完毕");
    }
}
